package com.xqboss.apps.service.sys;

import com.xqboss.apps.constant.Config;
import com.xqboss.apps.dto.punch.EditPunchConfigDto;
import com.xqboss.apps.dto.user.WalletProfileDto;
import com.xqboss.apps.service.equipment.EquipmentService;
import com.xqboss.apps.service.punch.PunchWeakenConfigService;
import com.xqboss.apps.vo.equipment.EquipmentPunchConfigVo;
import com.xqboss.apps.vo.sys.AppProfileVo;
import com.xqboss.apps.vo.sys.AppRechargeProfileVo;
import com.xqboss.apps.vo.sys.TeamProfileVo;
import com.xqboss.apps.vo.sys.WalletProfileVo;
import com.xqboss.common.exception.ServiceException;
import com.xqboss.system.service.ISysConfigService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.Map;
import java.util.Objects;

/**
 * <p>
 *     配置服务
 * </p>
 * @author Trent
 * @date 2023/9/11
 */
@Service
public class ConfigService {

    @Autowired
    private ISysConfigService sysConfigService;

    @Autowired
    private PunchWeakenConfigService punchWeakenConfigService;

    @Autowired
    private EquipmentService equipmentService;

    /**
     * 更新打卡配置
     * @param dto
     */
    @Transactional(rollbackFor = Exception.class)
    public void updatePunchConfig(EditPunchConfigDto dto) {
        boolean update = sysConfigService.updateConfig(Config.Sys.Punch.日打卡收益上限, dto.getDayIncomeMax());
        if(!update){
            throw new ServiceException("操作失败！");
        }
        update = sysConfigService.updateConfig(Config.Sys.Punch.收益折算系数, dto.getIncomeRatio());
        if(!update){
            throw new ServiceException("操作失败！");
        }
        // 耐久度倍数和破损值倍数修改时，需要对装备从新计算
        boolean changeDurabilityRate = false;
        BigDecimal durabilityRate = sysConfigService.getValue(Config.Sys.Punch.耐久度倍数);
        if(durabilityRate.compareTo(dto.getDurabilityRate()) != 0){
            update = sysConfigService.updateConfig(Config.Sys.Punch.耐久度倍数, dto.getDurabilityRate());
            if(!update){
                throw new ServiceException("操作失败！");
            }
            changeDurabilityRate = true;
        }
        boolean changeBreakageRate = false;
        BigDecimal breakageRate = sysConfigService.getValue(Config.Sys.Punch.破损度倍数);
        if(breakageRate.compareTo(dto.getBreakageRate()) != 0){
            update = sysConfigService.updateConfig(Config.Sys.Punch.破损度倍数, dto.getBreakageRate());
            if(!update){
                throw new ServiceException("操作失败！");
            }
            changeBreakageRate = true;
        }
        update = sysConfigService.updateConfig(Config.Sys.Punch.耐久消耗系数, dto.getDurabilityUseRatio());
        if(!update){
            throw new ServiceException("操作失败！");
        }
        update = sysConfigService.updateConfig(Config.Sys.Punch.耐久维修系数, dto.getDurabilityRepairsRatio());
        if(!update){
            throw new ServiceException("操作失败！");
        }
        update = sysConfigService.updateConfig(Config.Sys.Punch.耐久维修系数_扳手, dto.getDurabilityRepairsRatioWrench());
        if(!update){
            throw new ServiceException("操作失败！");
        }
        update = sysConfigService.updateConfig(Config.Sys.Punch.维修消耗等级_扳手, dto.getRepairsLevelWrench());
        if(!update){
            throw new ServiceException("操作失败！");
        }
        update = sysConfigService.updateConfig(Config.Sys.Punch.消耗破损值, dto.getBreakageUse());
        if(!update){
            throw new ServiceException("操作失败！");
        }
        punchWeakenConfigService.setConfig(dto.getWeakenConfigs());
        if(changeDurabilityRate || changeBreakageRate){
            equipmentService.updateEquipmentConfig(
                    changeDurabilityRate ? dto.getDurabilityRate() : null,
                    changeBreakageRate ? dto.getBreakageRate() : null
            );
        }
        sysConfigService.resetConfigCache();
    }

    /**
     * 获取打卡配置信息
     * @return
     */
    public EditPunchConfigDto getUpdateConfig() {
        EditPunchConfigDto result = new EditPunchConfigDto();
        result.setDayIncomeMax(sysConfigService.getValue(Config.Sys.Punch.日打卡收益上限));
        result.setIncomeRatio(sysConfigService.getValue(Config.Sys.Punch.收益折算系数));
        result.setDurabilityRate(sysConfigService.getValue(Config.Sys.Punch.耐久度倍数));
        result.setBreakageRate(sysConfigService.getValue(Config.Sys.Punch.破损度倍数));
        result.setDurabilityUseRatio(sysConfigService.getValue(Config.Sys.Punch.耐久消耗系数));
        //默认此耐久维修系数为（热豆）
        result.setDurabilityRepairsRatio(sysConfigService.getValue(Config.Sys.Punch.耐久维修系数));
        result.setDurabilityRepairsRatioWrench(sysConfigService.getValue(Config.Sys.Punch.耐久维修系数_扳手));
        result.setRepairsLevelWrench(sysConfigService.getValue(Config.Sys.Punch.维修消耗等级_扳手));
        result.setBreakageUse(sysConfigService.getValue(Config.Sys.Punch.消耗破损值));
        result.setWeakenConfigs(punchWeakenConfigService.getConfigList());
        return result;
    }

    /**
     * 获取钱包配置信息
     *
     * @return
     */
    public WalletProfileVo getWalletConfig(){
        WalletProfileVo result = new WalletProfileVo();
        result.setRechargeEnable(sysConfigService.getValue(Config.Sys.Recharge.充值功能开启状态));
        result.setRechargePayList(sysConfigService.getValue(Config.Sys.Recharge.支付方式));
        result.setRechargeInputAmount(sysConfigService.getValue(Config.Sys.Recharge.自定义充值));
        result.setRechargeAmountMin(sysConfigService.getValue(Config.Sys.Recharge.最低充值金额));
        result.setRechargeAmountMax(sysConfigService.getValue(Config.Sys.Recharge.最高充值金额));
        result.setRechargeExplain(sysConfigService.getValue(Config.Sys.Recharge.充值说明));

        result.setWithdrawEnable(sysConfigService.getValue(Config.Sys.Withdraw.提现功能开启状态));
        result.setWithdrawAmountMin(sysConfigService.getValue(Config.Sys.Withdraw.单次提现最低金额));
        result.setWithdrawAmountMax(sysConfigService.getValue(Config.Sys.Withdraw.单次提现最高金额));
        result.setWithdrawDayMax(sysConfigService.getValue(Config.Sys.Withdraw.当日提现金额上限));
        result.setWithdrawExplain(sysConfigService.getValue(Config.Sys.Withdraw.提现说明));
        return result;
    }

    /**
     * 修改钱包配置信息
     */
    public void updateWalletConfig(WalletProfileDto vo){
        if(Objects.nonNull(vo.getWithdrawAmountMin()) && Objects.nonNull(vo.getWithdrawAmountMax())){
            if(vo.getWithdrawAmountMax().compareTo(vo.getWithdrawAmountMin()) < 0){
                throw new ServiceException("最高提现金额不能低于最低提现金额");
            }
        }
        if(Objects.nonNull(vo.getRechargeAmountMin()) && Objects.nonNull(vo.getRechargeAmountMax())){
            if(vo.getRechargeAmountMax().compareTo(vo.getRechargeAmountMin()) < 0){
                throw new ServiceException("最高充值金额不能低于最低充值金额");
            }
        }

        // 更新提现配置
        boolean update = sysConfigService.updateConfig(Config.Sys.Withdraw.提现功能开启状态, vo.getWithdrawEnable());
        if(!update){
            throw new ServiceException("操作提现功能失败！");
        }
        update = sysConfigService.updateConfig(Config.Sys.Withdraw.单次提现最低金额, vo.getWithdrawAmountMin());
        if(!update){
            throw new ServiceException("操作提现最低金额失败！");
        }
        update = sysConfigService.updateConfig(Config.Sys.Withdraw.单次提现最高金额, vo.getWithdrawAmountMax());
        if(!update){
            throw new ServiceException("操作提现最高金额失败！");
        }
        update = sysConfigService.updateConfig(Config.Sys.Withdraw.当日提现金额上限, vo.getWithdrawDayMax());
        if(!update){
            throw new ServiceException("操作日提现上限失败！");
        }
        update = sysConfigService.updateConfig(Config.Sys.Withdraw.提现说明, vo.getWithdrawExplain());
        if(!update){
            throw new ServiceException("操作提现说明失败！");
        }

        // 更新充值配置
        update = sysConfigService.updateConfig(Config.Sys.Recharge.充值功能开启状态, vo.getRechargeEnable());
        if(!update){
            throw new ServiceException("操作充值功能失败！");
        }
        update = sysConfigService.updateConfig(Config.Sys.Recharge.支付方式, vo.getRechargePayList());
        if(!update){
            throw new ServiceException("操作充值支付方式失败！");
        }
        update = sysConfigService.updateConfig(Config.Sys.Recharge.自定义充值, vo.getRechargeInputAmount());
        if(!update){
            throw new ServiceException("操作自定义充值功能失败！");
        }
        update = sysConfigService.updateConfig(Config.Sys.Recharge.最低充值金额, vo.getRechargeAmountMin());
        if(!update){
            throw new ServiceException("操作最低充值金额失败！");
        }
        update = sysConfigService.updateConfig(Config.Sys.Recharge.最高充值金额, vo.getRechargeAmountMax());
        if(!update){
            throw new ServiceException("操作最高充值金额失败！");
        }
        update = sysConfigService.updateConfig(Config.Sys.Recharge.充值说明, vo.getRechargeExplain());
        if(!update){
            throw new ServiceException("操作充值说明失败！");
        }

        // 重置配置缓存
        sysConfigService.resetConfigCache();
    }

    /**
     * 获取APP配置
     * @return
     */
    public AppProfileVo getAppProfile() {
        AppProfileVo result = new AppProfileVo();
        result.setRechargeEnable(sysConfigService.getValue(Config.Sys.Recharge.充值功能开启状态));
        result.setRechargePayList(sysConfigService.getValue(Config.Sys.Recharge.支付方式));
        result.setRechargeInputAmount(sysConfigService.getValue(Config.Sys.Recharge.自定义充值));
        result.setRechargeAmountMin(sysConfigService.getValue(Config.Sys.Recharge.最低充值金额));
        result.setRechargeAmountMax(sysConfigService.getValue(Config.Sys.Recharge.最高充值金额));
        result.setRechargeExplain(sysConfigService.getValue(Config.Sys.Recharge.充值说明));
        result.setRechargeProtocol(sysConfigService.getValue(Config.Sys.Recharge.充值协议));

        result.setWithdrawEnable(sysConfigService.getValue(Config.Sys.Withdraw.提现功能开启状态));
        result.setWithdrawAmountMin(sysConfigService.getValue(Config.Sys.Withdraw.单次提现最低金额));
        result.setWithdrawAmountMax(sysConfigService.getValue(Config.Sys.Withdraw.单次提现最高金额));
        result.setWithdrawDayMax(sysConfigService.getValue(Config.Sys.Withdraw.当日提现金额上限));
        result.setWithdrawExplain(sysConfigService.getValue(Config.Sys.Withdraw.提现说明));

        result.setBuyKnow(sysConfigService.getValue(Config.Sys.Nft.购买须知));
        result.setCopyrightNotice(sysConfigService.getValue(Config.Sys.Nft.版权声明));
        result.setTeamGainRule(sysConfigService.getValue(Config.Sys.Punch.队伍增益规则));

        result.setPunchRuleExplain(sysConfigService.getValue(Config.Sys.Punch.打卡规则说明));

        result.setNpExplain(sysConfigService.getValue(Config.Sys.Punch.耐久破损度说明));
        result.setPunchUpvoteLove(sysConfigService.getValue(Config.Sys.Punch.提醒打卡点赞送爱心扣减数值));
        result.setIntegralLimit(sysConfigService.getValue(Config.Sys.Punch.新手引导积分阈值));
        result.setDurabilityLimit(sysConfigService.getValue(Config.Sys.Punch.耐久度收益递减阈值));

        result.setOrderPayType(sysConfigService.getValue(Config.Sys.Order.订单支付方式));
        result.setResaleNotice(sysConfigService.getValue(Config.Sys.Nft.转卖须知));
        result.setEquipmentUpgradeExplain(sysConfigService.getValue(Config.Sys.Nft.装备升级说明));
        result.setWrenchInviteRuleExplain(sysConfigService.getValue(Config.Sys.Other.扳手邀请规则说明));
        result.setIdentityUpgradeRuleExplain(sysConfigService.getValue(Config.Sys.Other.身份升级规则说明));
        result.setSynthesisExplain(sysConfigService.getValue(Config.Sys.Nft.合成规则说明));
        result.setOpenQuickCopyMinAmount(sysConfigService.getValue(Config.Sys.Market.开启快速抄货最低金额));
        result.setWrenchProductionExplain(sysConfigService.getValue(Config.Sys.Other.扳手生产规则));
        result.setWrenchProductionConfig(sysConfigService.getValue(Config.Sys.Other.扳手生产套餐说明));

        result.setGuildExplain(sysConfigService.getValue(Config.Sys.Guild.公会说明));

        result.setAvoidFrogExplain(sysConfigService.getValue(Config.Sys.Game.游戏公告躲避调皮蛙));
        result.setGetABreakExplain(sysConfigService.getValue(Config.Sys.Game.游戏公告时来运转));
        result.setGetABreakRule(sysConfigService.getValue(Config.Sys.Game.游戏规则时来运转));
        result.setFriedNewYearBeastExplain(sysConfigService.getValue(Config.Sys.Game.游戏公告炸年兽));

        result.setSportHelpExplain(sysConfigService.getValue(Config.Sys.Sport.运动场帮助说明));
        result.setSportHelpTeamExplain(sysConfigService.getValue(Config.Sys.Sport.运动场队伍帮助说明));
        result.setSportHelpBuildExplain(sysConfigService.getValue(Config.Sys.Sport.运动场建设帮助说明));
        return result;
    }


    /**
     * 获取APP充值配置
     * @return
     */
    public AppRechargeProfileVo getAppRechargeProfile() {
        AppRechargeProfileVo result = new AppRechargeProfileVo();
        result.setRechargeEnable(sysConfigService.getValue(Config.Sys.Recharge.充值功能开启状态));
        result.setRechargePayList(sysConfigService.getValue(Config.Sys.Recharge.支付方式));
        result.setRechargeInputAmount(sysConfigService.getValue(Config.Sys.Recharge.自定义充值));
        result.setRechargeAmountMin(sysConfigService.getValue(Config.Sys.Recharge.最低充值金额));
        result.setRechargeAmountMax(sysConfigService.getValue(Config.Sys.Recharge.最高充值金额));
        result.setRechargeExplain(sysConfigService.getValue(Config.Sys.Recharge.充值说明));
        result.setRechargeProtocol(sysConfigService.getValue(Config.Sys.Recharge.充值协议));
        return result;
    }

    /**
     * 修改热豆和办扳手配置
     * @param map
     */
    public void updateHotBeansConfig(Map<String, String> map) {
        // 热豆最大最小转卖数量配置
        String hotBeansMinCount = map.get(Config.Sys.Treasury.单次最低转卖数量);
        String hotBeansMaxCount = map.get(Config.Sys.Treasury.单次最高转卖数量);
        // 热豆最低最高价格配置
        String hotBeansMinPrice = map.get(Config.Sys.Treasury.热豆最低价);
        String hotBeansMaxPrice = map.get(Config.Sys.Treasury.热豆最高价);
        // 扳手最高最低转卖数量配置
        String wrenchMinCount = map.get(Config.Sys.Treasury.扳手单次最低转卖数量);
        String wrenchMaxCount = map.get(Config.Sys.Treasury.扳手单次最高转卖数量);
        // 扳手最低最高价格配置
        String wrenchMinPrice = map.get(Config.Sys.Treasury.扳手最低价);
        String wrenchMaxPrice = map.get(Config.Sys.Treasury.扳手最高价);
        // 力豆最高最低转卖数量配置
        String lidouMinCount = map.get(Config.Sys.Treasury.力豆单次最低转卖数量);
        String lidouMaxCount = map.get(Config.Sys.Treasury.力豆单次最高转卖数量);
        // 力豆最低最高价格配置
        String lidouMinPrice = map.get(Config.Sys.Treasury.力豆最低价);
        String lidouMaxPrice = map.get(Config.Sys.Treasury.力豆最高价);

        // 热豆转卖数量配置判断是否合理
        if (hotBeansMinCount != null && hotBeansMaxCount != null){
            if (Integer.parseInt(hotBeansMinCount) > Integer.parseInt(hotBeansMaxCount))
                throw new ServiceException("热豆单次转卖数量最低数量需小于等于最高数量");
        }

        // 热豆转卖价格配置判断是否合理
        if (hotBeansMinPrice !=null && hotBeansMaxPrice != null){
            if (Double.parseDouble(hotBeansMinPrice) > Double.parseDouble(hotBeansMaxPrice)){
                throw new ServiceException("热豆单次转卖最低价格需小于等于最高价格");
            }
        }

        // 扳手转卖数量配置判断是否合理
        if (wrenchMinCount !=null && wrenchMaxCount != null){
            if (Integer.parseInt(wrenchMinCount) > Integer.parseInt(wrenchMaxCount)){
                throw new ServiceException("扳手单次转卖数量最低数量需小于等于最高数量");
            }
        }
        // 扳手转卖价格配置判断是否合理
        if (wrenchMinPrice !=null && wrenchMaxPrice != null){
            if (Double.parseDouble(wrenchMinPrice) > Double.parseDouble(wrenchMaxPrice)){
                throw new ServiceException("扳手单次转卖最低价格需小于等于最高价格");
            }
        }

        // 力豆转卖数量配置判断是否合理
        if (lidouMinCount !=null && lidouMaxCount != null){
            if (Integer.parseInt(lidouMinCount) > Integer.parseInt(lidouMaxCount)){
                throw new ServiceException("力豆单次转卖数量最低数量需小于等于最高数量");
            }
        }
        // 力豆转卖价格配置判断是否合理
        if (lidouMinPrice !=null && lidouMaxPrice != null){
            if (Double.parseDouble(lidouMinPrice) > Double.parseDouble(lidouMaxPrice)){
                throw new ServiceException("力豆单次转卖最低价格需小于等于最高价格");
            }
        }

        for (Map.Entry<String,String> entry:map.entrySet()){
            sysConfigService.updateByKey(entry.getKey(),entry.getValue());
        }
        // 重置配置缓存
        sysConfigService.resetConfigCache();
    }

    /**
     * 获取队伍配置
     * @return
     */
    public TeamProfileVo getTeamProfile() {
        TeamProfileVo result = new TeamProfileVo();
        result.setUpgradeSwitch(sysConfigService.getValue(Config.Sys.Team.升级开关));
        result.setMaxLevel(sysConfigService.getValue(Config.Sys.Team.最高等级));
        result.setExpandRange(sysConfigService.getValue(Config.Sys.Team.人员扩充幅度));
        result.setPunchCount(sysConfigService.getValue(Config.Sys.Team.升级打卡次数叠加));
        result.setIncreaseRate(sysConfigService.getValue(Config.Sys.Team.升级增幅比例叠加));
        result.setFamilyMemberAward(sysConfigService.getValue(Config.Sys.Team.家庭主成员奖励抽成));
        result.setCaptainAward(sysConfigService.getValue(Config.Sys.Team.队长奖励抽成));
        return result;
    }

    /**
     * 修改队伍配置信息
     */
    public void updateTeamConfig(TeamProfileVo vo){

        // 更新队伍升级配置
        boolean update = sysConfigService.updateConfig(Config.Sys.Team.升级开关, vo.getUpgradeSwitch());
        if(!update){
            throw new ServiceException("操作队伍升级失败！");
        }
        update = sysConfigService.updateConfig(Config.Sys.Team.最高等级, vo.getMaxLevel());
        if(!update){
            throw new ServiceException("操作队伍最高等级失败！");
        }
        update = sysConfigService.updateConfig(Config.Sys.Team.人员扩充幅度, vo.getExpandRange());
        if(!update){
            throw new ServiceException("操作人员扩充幅度失败！");
        }
        update = sysConfigService.updateConfig(Config.Sys.Team.升级打卡次数叠加, vo.getPunchCount());
        if(!update){
            throw new ServiceException("操作升级打卡次数叠加失败！");
        }
        update = sysConfigService.updateConfig(Config.Sys.Team.升级增幅比例叠加, vo.getIncreaseRate());
        if(!update){
            throw new ServiceException("操作升级增幅比例叠加失败！");
        }
        update = sysConfigService.updateConfig(Config.Sys.Team.家庭主成员奖励抽成, vo.getFamilyMemberAward());
        if(!update){
            throw new ServiceException("操作家庭主成员奖励抽成失败！");
        }
        update = sysConfigService.updateConfig(Config.Sys.Team.队长奖励抽成, vo.getCaptainAward());
        if(!update){
            throw new ServiceException("操作队长奖励抽成失败！");
        }

        // 重置配置缓存
        sysConfigService.resetConfigCache();
    }

    /**
     * app获取打卡配置相关系数
     * @return
     */
    public EquipmentPunchConfigVo getPunchConfigByApp() {
        EquipmentPunchConfigVo result = new EquipmentPunchConfigVo();
        result.setIncomeRatio(sysConfigService.getValue(Config.Sys.Punch.收益折算系数));
        result.setDurabilityUseRatio(sysConfigService.getValue(Config.Sys.Punch.耐久消耗系数));
        //默认此耐久维修系数为（热豆）
        result.setWeakenConfigs(punchWeakenConfigService.getConfigList());
        return result;
    }
}
